package ch.mtb.conwin;
import java.awt.Color;
import ch.mtb.conwin.Config;

public class Genome {

	private double mutationRate ;//0.1;//1e-2;
	
	private double mRateOfMut = 1e-2;			//mutation rate factor of the mutation rate

	protected int reactions[];

	private int x, y;


	/**
	 * Creates a genome and initializes it with random values.There are 2^8 =
	 * 256 different situations, the first neighbouring field is in the top left
	 * corner, then clockwise. Each neigbouring field can contain another player
	 * or none (0/1). so each situation can be represented as a binary number i.
	 * The i-th position in genomeArray contains the number of the field, where
	 * the player will move to in this situation.
	 */

	public Genome() {
		initDna();
		x = 1;
		y = 1;
		mutationRate = 0.02+Config.getR().nextDouble()*0.1;
		
	}

	protected void initDna(){
		reactions = new int[256];

		for (int i = 0; i < 256; i++) {
			reactions[i] = Config.getR().nextInt(8);
			// System.out.println(reactions[i]);

		}
	
	}
	
	
	public Genome(int dNA[]) {

		initDna();

		reactions = dNA;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public void setX(int i) {
		x = i;
	}

	public void setY(int i) {
		y = i;
	}

	public Genome getClone() {
		int tempReactions[] = new int[256];

		for (int i = 0; i < 256; i++)
			tempReactions[i] = reactions[i];

		Genome temp = new Genome(tempReactions);

		return temp;

	}

	/**
	 * Accepts a situation as input ( an integer between 0 and 255) and gives
	 * back the number of the neighbouring field to move to (an integer between
	 * 1 and 8)
	 */

	public int react(int input) throws Exception {
		if ((input > 255) || (input < 0)) {
			System.out.println("genome: input out of range");
			throw new Exception("SE THROW");
		}
		// hier sollte eine exception geworfen werden, falls..

		return (int) reactions[input];

	}

	public Genome replicate() throws Exception {
		try {
			return getClone().mutate();
		} catch (Exception e) {
			System.out.println("replication failed");
			throw new Exception();
		}

	}

	// TODO add mutation
	public Genome mutate() {
		for (int i = 0; i < reactions.length; i++){
			if (Config.getR().nextDouble() < mutationRate){
				reactions[i] = Config.getR().nextInt(8);
			}
		}
		mutationRate = mutationRate + mRateOfMut*mutationRate*(Config.getR().nextDouble()-0.5);
		if (mutationRate < 0) mutationRate= 1e-20;
		if (mutationRate > 1) mutationRate=1- 1e-20;
		System.out.println("Mutationrate: " + mutationRate);
		return this;
	}

	public Color getColor() {
		int identifier = 0;
		for (int i = 0; i < 3; i++) {

			identifier = identifier + (int) Math.pow((double) 8, (double) i)
					* reactions[i];

		}
		// System.out.println(identifier);
		float hue = (float) identifier / (float) 512;
		// System.out.println(hue);
		return Color.getHSBColor(hue, 0.7f, 0.8f);
		// return Color.black;
	}

}